package socket;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import com.sun.security.ntlm.Client;

import Static.StaticTest;
import stream.StreamUtil;
import test.Tclass;

public class MyServer2 {
	static boolean isClosed = false;

	public static void main(String[] args) throws Exception {
		final ExecutorService executorService = Executors
				.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * 4);
		final ServerSocket serverSocketForShutdown = new ServerSocket(5680);
		final ServerSocket server = new ServerSocket(5679);
		MyServer2 myServer = new MyServer2();

		//Socket socket = null;
		Thread operateThread = new Thread() {
			public void start() {
				this.setDaemon(true);
				super.start();
			}

			public void run() {

				while (true) {
					Socket shutdownSocket = null;
					try {
						shutdownSocket = serverSocketForShutdown.accept();
						shutdownSocket.setSoLinger(true, 100);//设置socket关闭延迟时间，目的是让流中已有的数据处理完
						BufferedReader bufferedReader = new BufferedReader(
								new InputStreamReader(shutdownSocket.getInputStream()));
						PrintWriter printWriter = new PrintWriter(shutdownSocket.getOutputStream());
						//						printWriter.println("shutdownSocket is operating...");
						//						printWriter.flush();
						while (true) {
							String readLine = bufferedReader.readLine();
							printWriter.println("shutdownSocket:" + readLine);
							printWriter.flush();
							if (readLine.equals("bye")) {
								System.out.println("in bye1");
								isClosed = true;
								executorService.shutdown();
								while (!executorService.isTerminated()) {
									executorService.awaitTermination(30, TimeUnit.SECONDS);
									System.out.println("in bye");
								}
								server.close();
								printWriter.println("shutdownSocket is closing...");
								printWriter.flush();
								shutdownSocket.shutdownOutput();//半关闭输出流
								shutdownSocket.close();
								serverSocketForShutdown.close();
							}
						}
					} catch (IOException e) {
						e.printStackTrace();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		};
		operateThread.start();
		while (!isClosed) {
			Socket socket = null;
			try {
				socket = server.accept();
				socket.setSoTimeout(10000);
				Thread thread = myServer.new mkServer(socket);
				executorService.execute(thread);
			} catch (SocketTimeoutException e) {
				e.printStackTrace();
				StreamUtil.fileOutputStream(e.getMessage());
			} catch (RejectedExecutionException e) {
				try {
					if (socket != null)
						socket.close();
				} catch (Exception e2) {
					e.printStackTrace();
					StreamUtil.fileOutputStream(e2.getMessage());
				}
				return;
			} catch (SocketException e) {
				e.printStackTrace();
				StreamUtil.fileOutputStream(e.getMessage());
				if (e.getMessage().indexOf("socket closed") != -1)
					return;
			} catch (IOException e) {
				e.printStackTrace();
				StreamUtil.fileOutputStream(e.getMessage());
			}
		}
	}

	public class mkServer extends Thread {
		Socket sSocket = new Socket();

		public mkServer(Socket sSocket) {
			this.sSocket = sSocket;
		}

		public void run() {
			try {
				sockets(sSocket);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	public static void mkFile(BufferedReader in) throws IOException {
		java.io.File file = new java.io.File("D://a.txt");
		FileOutputStream fos = new FileOutputStream(file);
		try {
			fos.write(in.readLine().getBytes(), 0, 3);
		} catch (Exception e) {
			e.printStackTrace();
		}
		fos.close();
	}

	public static void sockets(Socket client) throws Exception {
		BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
		PrintWriter out = new PrintWriter(client.getOutputStream());
		int i = 0;
		while (true) {
			String str = in.readLine();
			System.out.println("server:" + str);
			out.println("has received:" + str);
			out.flush();
			/*try {
				mkFile(in);
			} catch (Exception e) {
				e.printStackTrace();
			}*/
			System.out.println("here");
			if (str.equals("end"))
				break;
		}
		client.close();
	}
}
